package com.xiang.community.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.code.kaptcha.Producer;
import com.xiang.community.annotation.LoginRequired;
import com.xiang.community.dto.LogDTO;
import com.xiang.community.dto.ResultDTO;
import com.xiang.community.entity.User;
import com.xiang.community.enums.ResponseCodeEnum;
import com.xiang.community.service.CommonService;
import com.xiang.community.service.UserService;
import com.xiang.community.utils.CookieUtil;
import com.xiang.community.utils.ProducerUtil;
import com.xiang.community.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import static com.xiang.community.constant.LoginConstant.*;
import static com.xiang.community.constant.RedisUtilConstant.PREFIX_USER_ID;

@Slf4j
@RestController
public class LoginController {

    @Resource
    private UserService userService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private CommonService commonService;
    @Resource
    private HttpServletRequest request;

    @PostMapping("/registry")
    public ResultDTO register(@RequestBody LogDTO logDTO) {
        // 空值处理
        if (StringUtils.isBlank(logDTO.getUsername()) || StringUtils.isBlank(logDTO.getPassword()) ||
                StringUtils.isBlank(logDTO.getEmail()) || StringUtils.isBlank(logDTO.getKaptcha())) {
            return ResultDTO.builder().code(ResponseCodeEnum.CLIENT_ERROR.getCode()).message("注册失败,参数错误!").build();
        }

        String key = CookieUtil.getValue(request, KAPTCHA_KEY);
        if (StringUtils.isNotBlank(key) && redisUtil.getValueFromString(KAPTCHA_KEY, key).equals(logDTO.getKaptcha().toUpperCase())) {
            return userService.register(logDTO.getUsername(), logDTO.getPassword(), logDTO.getEmail());
        }
        return ResultDTO.builder().code(ResponseCodeEnum.CLIENT_ERROR.getCode()).message("注册失败,验证码错误!").build();
    }

    @GetMapping("/activation/{userId}/{code}")
    public ResultDTO activation(@PathVariable("userId") int userId, @PathVariable("code") String code) {
        if (StringUtils.isBlank(code)) {
            return ResultDTO.builder().code(ResponseCodeEnum.CLIENT_ERROR.getCode()).message("激活失败,验证码错误!").build();
        }
        return userService.activation(userId, code);
    }

    @PostMapping("/login")
    public ResultDTO login(@RequestBody LogDTO logDTO) throws JsonProcessingException {
        String key = CookieUtil.getValue(request, KAPTCHA_KEY);
        // 空值处理
        if (StringUtils.isBlank(key) || StringUtils.isBlank(logDTO.getUsername()) || StringUtils.isBlank(logDTO.getPassword()) ||
                StringUtils.isBlank(logDTO.getKaptcha())) {
            return ResultDTO.builder().code(ResponseCodeEnum.CLIENT_ERROR.getCode()).message("登录失败,参数错误!").build();
        }

        return userService.login(logDTO.getUsername(), logDTO.getPassword(), logDTO.getKaptcha(),
                redisUtil.getValueFromString(KAPTCHA_KEY, key));
    }

    @LoginRequired
    @GetMapping("/logout")
    public ResultDTO logout() {
        return userService.logout(CookieUtil.getValue(request, MAP_KEY_TOKEN));
    }

    @LoginRequired
    @GetMapping("/userData")
    public ResultDTO userData() {
        Map<String, Object> map = new HashMap<>(1);
        String currentUserId = redisUtil.getValueFromString(PREFIX_USER_ID, CookieUtil.getValue(request, MAP_KEY_TOKEN));
        User user = commonService.getUserByUserId(currentUserId);
        map.put(MAP_KEY_INFO, user);
        return ResultDTO.builder().code(ResponseCodeEnum.SUCCESS.getCode()).data(map).build();
    }

    @RequestMapping(path = "/kaptcha", method = RequestMethod.GET)
    public void getKaptcha(HttpServletResponse response) {
        // 生成验证码
        Producer producer = ProducerUtil.KAPATCHAPRODUCER.getKaptchaProducer();
        String text = producer.createText();
        BufferedImage image = producer.createImage(text);

        // 存入Redis
        String key = CookieUtil.getValue(request, KAPTCHA_KEY);
        redisUtil.saveIntoString(KAPTCHA_KEY, key, text);

        // 将图片输出给浏览器
        response.setContentType("image/png");
        try {
            OutputStream os = response.getOutputStream();
            ImageIO.write(image, "png", os);
        } catch (IOException e) {
            log.error("响应验证码失败:" + e.getMessage());
        }
    }

    @GetMapping("/kaptchaKey")
    public ResultDTO getKaptchaKey() {
        String kaptchaKey = UUID.randomUUID().toString();
        Map<String, Object> map = new HashMap<>(2);
        map.put(KAPTCHA_KEY, kaptchaKey);
        // 3分钟
        map.put("expired", new Date(System.currentTimeMillis() + 3 * 60 * 1000));
        return ResultDTO.builder().code(ResponseCodeEnum.SUCCESS.getCode()).data(map).build();
    }
}
